1# Mutators Tutorial
  2
  3<!-- TOC -->
  4
  5## 3D Space Halving
  6Sometimes you want to take a 3D shape like a sphere, and cut it in half.
  7The BOSL2 library provides a number of ways to do this:
  8
  9```openscad-3D
 10include <BOSL2/std.scad>
 11left_half()
 12  sphere(d=100);
 13```
 14
 15```openscad-3D
 16include <BOSL2/std.scad>
 17right_half()
 18  sphere(d=100);
 19```
 20
 21```openscad-3D
 22include <BOSL2/std.scad>
 23front_half()
 24  sphere(d=100);
 25```
 26
 27```openscad-3D
 28include <BOSL2/std.scad>
 29back_half()
 30  sphere(d=100);
 31```
 32
 33```openscad-3D
 34include <BOSL2/std.scad>
 35bottom_half()
 36  sphere(d=100);
 37```
 38
 39```openscad-3D
 40include <BOSL2/std.scad>
 41top_half()
 42  sphere(d=100);
 43```
 44
 45You can use the `half_of()` module if you want to split space in a way not aligned with an axis:
 46
 47```openscad-3D
 48include <BOSL2/std.scad>
 49half_of([-1,0,-1])
 50  sphere(d=100);
 51```
 52
 53The plane of dissection can be shifted along the axis of any of these operators:
 54
 55```openscad-3D
 56include <BOSL2/std.scad>
 57left_half(x=20)
 58  sphere(d=100);
 59```
 60
 61```openscad-3D
 62include <BOSL2/std.scad>
 63back_half(y=-20)
 64  sphere(d=100);
 65```
 66
 67```openscad-3D
 68include <BOSL2/std.scad>
 69bottom_half(z=20)
 70  sphere(d=100);
 71```
 72
 73```openscad-3D
 74include <BOSL2/std.scad>
 75half_of([-1,0,-1], cp=[20,0,20])
 76  sphere(d=100);
 77```
 78
 79By default, these operators can be applied to objects that fit in a cube 1000 on a side. If you need
 80to apply these halving operators to objects larger than this, you can give the size in the `s=`
 81argument:
 82
 83```openscad-3D
 84include <BOSL2/std.scad>
 85bottom_half(s=2000)
 86  sphere(d=1500);
 87```
 88
 89## 2D Plane Halving
 90To cut 2D shapes in half, you will need to add the `planar=true` argument:
 91
 92```openscad-3D
 93include <BOSL2/std.scad>
 94left_half(planar=true)
 95  circle(d=100);
 96```
 97
 98```openscad-3D
 99include <BOSL2/std.scad>
100right_half(planar=true)
101  circle(d=100);
102```
103
104```openscad-3D
105include <BOSL2/std.scad>
106front_half(planar=true)
107  circle(d=100);
108```
109
110```openscad-3D
111include <BOSL2/std.scad>
112back_half(planar=true)
113  circle(d=100);
114```
115
116## Chained Mutators
117If you have a set of shapes that you want to do pair-wise hulling of, you can use `chain_hull()`:
118
119```openscad-3D
120include <BOSL2/std.scad>
121chain_hull() {
122  cube(5, center=true);
123  translate([30, 0, 0]) sphere(d=15);
124  translate([60, 30, 0]) cylinder(d=10, h=20);
125  translate([60, 60, 0]) cube([10,1,20], center=false);
126}
127```
128
129## Extrusion Mutators
130The OpenSCAD `linear_extrude()` module can take a 2D shape and extrude it vertically in a line:
131
132```openscad-3D
133include <BOSL2/std.scad>
134linear_extrude(height=30)
135  zrot(45)
136    square(40,center=true);
137```
138
139The `rotate_extrude()` module can take a 2D shape and rotate it around the Z axis.
140
141```openscad-3D
142include <BOSL2/std.scad>
143rotate_extrude()
144  left(50) zrot(45)
145    square(40,center=true);
146```
147
148In a similar manner, the BOSL2 `cylindrical_extrude()` module can take a 2d shape and extrude it
149out radially from the center of a cylinder:
150
151```openscad-3D
152include <BOSL2/std.scad>
153cylindrical_extrude(or=40, ir=35)
154  text(text="Hello World!", size=10, halign="center", valign="center");
155```
156
157
158## Offset Mutators
159
160### Minkowski Difference
161Openscad provides the `minkowski()` module to trace a shape over the entire surface of another shape:
162
163```openscad-3D
164include <BOSL2/std.scad>
165minkowski() {
166  union() {
167	cube([100,33,33], center=true);
168	cube([33,100,33], center=true);
169	cube([33,33,100], center=true);
170  }
171  sphere(r=8);
172}
173```
174
175However, it doesn't provide the inverse of this operation; to remove a shape from the entire surface
176of another object.  For this, the BOSL2 library provides the `minkowski_difference()` module:
177
178```openscad-3D
179include <BOSL2/std.scad>
180minkowski_difference() {
181  union() {
182    cube([100,33,33], center=true);
183    cube([33,100,33], center=true);
184    cube([33,33,100], center=true);
185  }
186  sphere(r=8);
187}
188```
189
190To perform a `minkowski_difference()` on 2D shapes, you need to supply the `planar=true` argument:
191
192```openscad-2D
193include <BOSL2/std.scad>
194minkowski_difference(planar=true) {
195  union() {
196    square([100,33], center=true);
197    square([33,100], center=true);
198  }
199  circle(r=8);
200}
201```
202
203### Round2d
204The `round2d()` module lets you take a 2D shape and round inside and outside corners.  The inner concave corners are rounded to the radius `ir=`, while the outer convex corners are rounded to the radius `or=`:
205
206```openscad-2D
207include <BOSL2/std.scad>
208round2d(or=8)
209  star(6, step=2, d=100);
210```
211
212```openscad-2D
213include <BOSL2/std.scad>
214round2d(ir=12)
215  star(6, step=2, d=100);
216```
217
218```openscad-2D
219include <BOSL2/std.scad>
220round2d(or=8,ir=12)
221  star(6, step=2, d=100);
222```
223
224You can use `r=` to effectively set both `ir=` and `or=` to the same value:
225
226```openscad-2D
227include <BOSL2/std.scad>
228round2d(r=8)
229  star(6, step=2, d=100);
230```
231
232### Shell2d
233With the `shell2d()` module, you can take an arbitrary shape, and get the shell outline of it.
234With a positive thickness, the shell is offset outwards from the original shape:
235
236```openscad-2D
237include <BOSL2/std.scad>
238shell2d(thickness=5)
239  star(5,step=2,d=100);
240color("blue")
241  stroke(star(5,step=2,d=100),closed=true);
242```
243
244With a negative thickness, the shell if inset from the original shape:
245
246```openscad-2D
247include <BOSL2/std.scad>
248shell2d(thickness=-5)
249  star(5,step=2,d=100);
250color("blue")
251  stroke(star(5,step=2,d=100),closed=true);
252```
253
254You can give a pair of thickness values if you want it both inset and outset from the original shape:
255
256```openscad-2D
257include <BOSL2/std.scad>
258shell2d(thickness=[-5,5])
259  star(5,step=2,d=100);
260color("blue")
261  stroke(star(5,step=2,d=100),closed=true);
262```
263
264You can add rounding to the outside by passing a radius to the `or=` argument.
265
266```openscad-2D
267include <BOSL2/std.scad>
268shell2d(thickness=-5,or=5)
269  star(5,step=2,d=100);
270```
271
272If you need to pass different radii for the convex and concave corners of the outside, you can pass them as `or=[CONVEX,CONCAVE]`:
273
274```openscad-2D
275include <BOSL2/std.scad>
276shell2d(thickness=-5,or=[5,10])
277  star(5,step=2,d=100);
278```
279
280A radius of 0 can be used to specify no rounding:
281
282```openscad-2D
283include <BOSL2/std.scad>
284shell2d(thickness=-5,or=[5,0])
285  star(5,step=2,d=100);
286```
287
288You can add rounding to the inside by passing a radius to the `ir=` argument.
289
290```openscad-2D
291include <BOSL2/std.scad>
292shell2d(thickness=-5,ir=5)
293  star(5,step=2,d=100);
294```
295
296If you need to pass different radii for the convex and concave corners of the inside, you can pass them as `ir=[CONVEX,CONCAVE]`:
297
298```openscad-2D
299include <BOSL2/std.scad>
300shell2d(thickness=-5,ir=[8,3])
301  star(5,step=2,d=100);
302```
303
304You can use `or=` and `ir=` together to get nice combined rounding effects:
305
306```openscad-2D
307include <BOSL2/std.scad>
308shell2d(thickness=-5,or=[7,2],ir=[7,2])
309  star(5,step=2,d=100);
310```
311
312```openscad-2D
313include <BOSL2/std.scad>
314shell2d(thickness=-5,or=[5,0],ir=[5,0])
315  star(5,step=2,d=100);
316```
317
318
319### Round3d
320### Offset3d
321(To be Written)
322
323
324## Color Manipulators
325The built-in OpenSCAD `color()` module can let you set the RGB color of an object, but it's often
326easier to select colors using other color schemes.  You can use the HSL or Hue-Saturation-Lightness
327color scheme with the `hsl()` module:
328
329```openscad-3D
330include <BOSL2/std.scad>
331n = 10; size = 100/n;
332for (a=count(n), b=count(n), c=count(n)) {
333  let( h=360*a/n, s=1-b/(n-1), l=c/(n-1))
334  translate(size*[a,b,c]) {
335    hsl(h,s,l) cube(size);
336  }
337}
338```
339
340You can use the HSV or Hue-Saturation-Value color scheme with the `hsv()` module:
341
342```openscad-3D
343include <BOSL2/std.scad>
344n = 10; size = 100/n;
345for (a=count(n), b=count(n), c=count(n)) {
346  let( h=360*a/n, s=1-b/(n-1), v=c/(n-1))
347  translate(size*[a,b,c]) {
348    hsv(h,s,v) cube(size);
349  }
350}
351```
352
353